package com.kalvan.core.http;

import org.apache.commons.lang3.StringUtils;

import java.net.*;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author chenliang
 */
public class HttpUrlUtils {

    public static final String REGEX = "^(127\\.0\\.0\\.1)|(localhost)|(10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|(172\\.((1[6-9])|(2\\d)|(3[01]))\\.\\d{1,3}\\.\\d{1,3})|(192\\.168\\.\\d{1,3}\\.\\d{1,3})$";
    static Set<String> excluded = new HashSet<>();

    /**
     * 排除内部的url
     *
     * @param url url
     */
    public static void initExcluded(String url) {
        excluded.add(url);

    }

    /**
     * 判断是否有为有效地址,不包括内网和局域网地址,通知时可以检查
     *
     * @param url url
     * @return boolean
     */
    public static boolean isUrl(String url) {
        if (StringUtils.isBlank(url)) {
            return false;
        }
        try {
            URL urlObject = new URL(url);
            String host = urlObject.getHost();
            //地址可用性探测
//            InetAddress address = InetAddress.getByName(host);
//            if (host.equalsIgnoreCase(address.getHostAddress())) {
            if (isIPAddress(host)) {
                if (isInner(host)) {
                    return excluded.contains(host);
                }
            } else if ("localhost".equals(host)) {
                return excluded.contains(host);
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public static boolean isIPAddress(String str) {
        // 如果长度不符合条件 返回false
        String regex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
        // 判断ip地址是否与正则表达式匹配
        if (str.matches(regex)) {
            String[] arr = str.split("\\.");
            for (int i = 0; i < 4; i++) {
                int temp = Integer.parseInt(arr[i]);
                //如果某个数字不是0到255之间的数 就返回false
                if (temp < 0 || temp > 255) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }

    }

    /**
     * 下则判断是否为内网地址
     * A类    10.0.0.0—10.255.255.255
     * B类    172.16.0.0—172.31.255.255
     * C类    192.168.0.0—192.168.255.255
     *
     * @param ip ip
     * @return boolean
     */
    public static boolean isInner(String ip) {
        if (ip.startsWith("110.") || ip.startsWith("210")) {
            //避免 110. 210. 和 10.内部ip的冲突
            return false;
        }
        // 是否内网ip地址
        Pattern reg = Pattern.compile(REGEX);
        Matcher matcher = reg.matcher(ip);
        return matcher.find();
    }


    /**
     * 获取域名或者ip部分
     *
     * @param url url
     * @return String
     */
    public static String getDomain(String url) {
        try {
            URI uri = new URI(url);
            URI effectiveURI = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
            return effectiveURI.toString();
        } catch (URISyntaxException e) {

        }
        return "";
    }

    private static String localIp;

    public static String localIP() {
        try {
            if (!StringUtils.isEmpty(localIp)) {
                return localIp;
            } else {
                String ip = System.getProperty("com.alibaba.nacos.client.naming.local.ip", InetAddress.getLocalHost().getHostAddress());
                localIp = ip;
                return ip;
            }
        } catch (UnknownHostException var1) {
            return "resolve_failed";
        }
    }

    public static void main(String[] args) throws URISyntaxException {
        System.out.println(isUrl("http://127.0.0.1"));
        System.out.println(isUrl("http://10.0.0.1"));
        System.out.println(isUrl("http://localhost/xxx"));
        System.out.println(isUrl("www.baidu.com/xxx/1231231x"));
        System.out.println(isUrl("http://kalvn.store/xxx/1231231x"));
        System.out.println(isUrl("http://xxx.kalvn.store/xxx/1231231x"));
        System.out.println(getDomain("www.baidu.com/xxx/1231231x"));
        System.out.println(getDomain("http://www.baidu.com/xxx/1231231x"));
        System.out.println(getDomain("http://www.baidu.com:88/xxx/1231231x"));
        System.out.println(getDomain("http://123456:88/xxx/1231231x"));
        System.out.println(getDomain("https://123456:88/xxx/1231231x"));
        System.out.println(getDomain("123.456:88/xxx/1231231x"));
    }
}
